"""
@File    :   validate.py
@Time    :   2024/04/14 16:31:23
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   系统配置相关的验证模型
"""

from pydantic import BaseModel, Field, FieldValidationInfo, constr, field_validator

from src.business.admin.system.settings.enums import (
    LoginFailureLockoutPolicyEnum,
    PasswordStrengthEnum,
)
from src.config import get_app_settings
from src.schemas.validate import BaseValidateSchemaConfigMixin
from src.schemas.validator_func.simple_validator import unique_list_validator

# 获取应用配置
settings = get_app_settings()


class SystemSettingsCreateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于创建系统设置的验证模型"""

    min_password_length: int = Field(default=8, ge=6, le=20, description="密码最小长度")
    max_password_length: int = Field(
        default=20, ge=6, le=20, description="密码最大长度"
    )
    password_strength: PasswordStrengthEnum = Field(
        default=PasswordStrengthEnum.high.value, description="密码强度要求"
    )
    login_failure_lockout_policy: LoginFailureLockoutPolicyEnum = Field(
        default=LoginFailureLockoutPolicyEnum.lock_username.value,
        description="登录失败锁定策略",
    )
    login_failure_lockout_times: int = Field(
        default=10, ge=1, le=100, description="登录失败锁定次数"
    )
    login_failure_lock_minutes: int = Field(
        default=5, ge=1, le=3000, description="登录失败锁定时间(分钟)"
    )
    # 文件上传相关
    user_avatar_image_upload_max_size: int = Field(
        default=settings.default_upload_avatar_max_size,
        ge=1,
        le=9999,
        description="上传用户头像的最大大小(单位: MB)",
    )
    user_avatar_image_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^\.[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_avatar_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的用户头像图片格式",
    )
    image_upload_max_size: int = Field(
        default=settings.default_upload_image_max_size,
        ge=1,
        le=9999,
        description="上传图片的最大大小(单位: MB)",
    )
    image_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^\.[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_image_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的图片格式",
    )
    video_upload_max_size: int = Field(
        default=settings.default_upload_video_max_size,
        ge=1,
        le=9999,
        description="上传视频的最大大小(单位: MB)",
    )
    video_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^\.[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_video_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的视频格式",
    )

    file_upload_max_size: int = Field(
        default=settings.default_upload_file_max_size,
        ge=1,
        le=9999,
        description="上传文件的最大大小(单位: MB)",
    )
    file_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^\.[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_file_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的文件格式",
    )

    # 验证器
    @field_validator("max_password_length")
    @classmethod
    def validate_psw_length(cls, max_password_length: int, info: FieldValidationInfo):
        min_password_length = info.data["min_password_length"]
        if max_password_length < min_password_length:
            raise ValueError("密码最大长度不能小于最小长度")
        return max_password_length

    validator_list_unique = field_validator(
        "user_avatar_image_upload_type",
        "image_upload_type",
        "video_upload_type",
        "file_upload_type",
    )(classmethod(unique_list_validator))


class SystemSettingsUpdateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于修改系统设置的验证模型"""

    min_password_length: int = Field(default=8, ge=6, le=20, description="密码最小长度")
    max_password_length: int = Field(
        default=20, ge=6, le=20, description="密码最大长度"
    )
    password_strength: PasswordStrengthEnum = Field(
        default=PasswordStrengthEnum.high.value, description="密码强度要求"
    )
    login_failure_lockout_policy: LoginFailureLockoutPolicyEnum = Field(
        default=LoginFailureLockoutPolicyEnum.lock_username.value,
        description="登录失败锁定策略",
    )
    login_failure_lockout_times: int = Field(
        default=10, ge=1, le=100, description="登录失败锁定次数"
    )
    login_failure_lock_minutes: int = Field(
        default=5, ge=1, le=3000, description="登录失败锁定时间(分钟)"
    )
    # 文件上传相关
    user_avatar_image_upload_max_size: int = Field(
        default=settings.default_upload_avatar_max_size,
        ge=1,
        le=9999,
        description="上传用户头像的最大大小(单位: MB)",
    )
    user_avatar_image_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_avatar_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的用户头像图片格式",
    )
    image_upload_max_size: int = Field(
        default=settings.default_upload_image_max_size,
        ge=1,
        le=9999,
        description="上传图片的最大大小(单位: MB)",
    )
    image_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_image_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的图片格式",
    )
    video_upload_max_size: int = Field(
        default=settings.default_upload_video_max_size,
        ge=1,
        le=9999,
        description="上传视频的最大大小(单位: MB)",
    )
    video_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_video_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的视频格式",
    )

    file_upload_max_size: int = Field(
        default=settings.default_upload_file_max_size,
        ge=1,
        le=9999,
        description="上传文件的最大大小(单位: MB)",
    )
    file_upload_type: list[
        constr(
            strip_whitespace=True,
            min_length=1,
            max_length=10,
            pattern=r"^[a-zA-Z0-9]+$",
            to_lower=True,
        )
    ] = Field(
        default=settings.default_allow_upload_file_suffix,
        min_length=1,
        max_length=200,
        description="允许上传的文件格式",
    )

    # 验证器
    @field_validator("max_password_length")
    @classmethod
    def validate_psw_length(cls, max_password_length: int, info: FieldValidationInfo):
        min_password_length = info.data["min_password_length"]
        if max_password_length < min_password_length:
            raise ValueError("密码最大长度不能小于最小长度")
        return max_password_length

    validator_list_unique = field_validator(
        "user_avatar_image_upload_type",
        "image_upload_type",
        "video_upload_type",
        "file_upload_type",
    )(classmethod(unique_list_validator))
